#include "Worker.h"
#include "BehaviorManager.h"
#include "BaseBehavior.h"
#include "../SGD Wrappers/SGD_Event.h"

Worker::Worker() : Listener(this)
{
	RegisterForEvent("ALARM_TRIGGER");
	RegisterForEvent("ALARM_OFF");

	RegisterForEvent("TARGET_FOUND");
	RegisterForEvent("STUNNED");
	m_FieldOfView.SetOwner(this);

	animation.m_strCurrAnimation = "worker";
	animation.m_fCurrDuration = 0.0f;
	animation.m_nCurrFrame = 0;


}


Worker::~Worker()
{
	
		UnregisterFromEvent("ALARM_TRIGGER");
		UnregisterFromEvent("ALARM_OFF");
		UnregisterFromEvent("TARGET_FOUND");
		UnregisterFromEvent("STUNNED");
}


/*virtual*/ void Worker::Update(float dt)	 /*override*/
{
	if (m_tStunTimer.Update(dt))
	{
		if (currBehavior != nullptr)
		{
			if (m_nAIState == PATROL)
			{
				if (currBehavior->Update(dt, this, *navGraph->GetVertexElement(currPath[m_nCurrPathNode])))
				{
					m_nCurrPathNode++;
					if (m_nCurrPathNode == currPath.size())
					{
						m_nCurrPathNode = 0;
						m_nCurrWaypoint++;
						if (m_nCurrWaypoint == m_vWayPoints.size())
							m_nCurrWaypoint = 0;

						navGraph->FindPath(m_vWayPoints[m_nCurrWaypoint], currPath[m_nCurrPathNode], currPath);

					}
				}
			}
			else if (m_nAIState == TO_ALARM)
			{
				if (currBehavior->Update(dt, this, *navGraph->GetVertexElement(currPath[m_nCurrPathNode])))
				{

					m_nCurrPathNode++;
					if (m_nCurrPathNode == currPath.size())
					{
						m_nCurrPathNode = 0;


						navGraph->FindPath(alarmNode, homeNode, currPath);
						m_nCurrWaypoint++;
						if (m_nCurrWaypoint == m_vWayPoints.size())
							m_nCurrWaypoint = 0;
						m_nAIState = GO_HOME;
					}
				}
			}
			else if (m_nAIState == GO_HOME)
			{
			if (currBehavior->Update(dt, this, *navGraph->GetVertexElement(currPath[m_nCurrPathNode])))
				{
					m_nCurrPathNode++;
					if (m_nCurrPathNode == currPath.size())
					{
						m_nCurrPathNode = 0;
						RetrieveBehavior("wait");
						m_nAIState = WAIT;
					}
				}
			}
			
			else if (m_nAIState == WAIT)
				currBehavior->Update(dt, this, SGD::Point());
		}
	}
	EnemyUnit::Update(dt);

}


/*virtual*/ void Worker::HandleEvent(const SGD::Event* pEvent)
{
	if (pEvent->GetEventID() == "ALARM_TRIGGER")
	{
		unsigned int closestNode;
		float distanceToNode = 70000;
		for (unsigned int i = 0; i < navGraph->size(); i++)
		{

			SGD::Point temp = *navGraph->GetVertexElement(i);
			float newDistance = (temp - m_ptPosition).ComputeLength();

			if (newDistance < distanceToNode)
			{
				distanceToNode = newDistance;
				closestNode = i;
			}

		}
		navGraph->FindPath(closestNode, homeNode, currPath);

		m_nAIState = GO_HOME;
		RetrieveBehavior("runTo");
	}
	if (pEvent->GetEventID() == "ALARM_OFF")
	{
		unsigned int closestNode;
		float distanceToNode = 70000;
		for (unsigned int i = 0; i < navGraph->size(); i++)
		{

			SGD::Point temp = *navGraph->GetVertexElement(i);
			float newDistance = (temp - m_ptPosition).ComputeLength();

			if (newDistance < distanceToNode)
			{
				distanceToNode = newDistance;
				closestNode = i;
			}

		}
		navGraph->FindPath(closestNode, m_vWayPoints[m_nCurrWaypoint], currPath);


		m_nAIState = PATROL;
		RetrieveBehavior("moveTo");
	}
	if (pEvent->GetEventID() == "TARGET_FOUND")
	{
		if (m_nAIState != TO_ALARM)
		{
			unsigned int closestNode;
			float distanceToNode = 70000;
			for (unsigned int i = 0; i < navGraph->size(); i++)
			{

				SGD::Point temp = *navGraph->GetVertexElement(i);
				float newDistance = (temp - m_ptPosition).ComputeLength();

				if (newDistance < distanceToNode)
				{
					distanceToNode = newDistance;
					closestNode = i;
				}

			}
			m_nCurrPathNode = 0;
			navGraph->FindPath(closestNode, alarmNode, currPath);
			m_nAIState = TO_ALARM;
			RetrieveBehavior("runTo");
		}
		
	}
	if (pEvent->GetEventID() == "STUNNED")
	{
		m_tStunTimer.AddTime(5);
	}


}

/*virtual*/ void Worker::HandleCollision(const IBase* pOther) /*override*/
{
	if (pOther->GetType() == OBJ_PLAYER)
	{
		m_nAIState = GO_HOME;
		RetrieveBehavior("runTo");

	}

	else if (pOther->GetType() == OBJ_TRIGGER || pOther->GetType() == OBJ_PLAYERCOLLISION)
	{

	}
	else
		MovingObject::HandleCollision(pOther);
}

void Worker::RetrieveBehavior(std::string name)
{

	if (currBehavior != nullptr)
	{
		currBehavior = nullptr;
	}
	currBehavior = BehaviorManager::GetInstance()->GetBehaviors()[name];
}

void Worker::SetHome(BaseObject* home)
{
	if (m_pHome != nullptr)
	{
		m_pHome->Release();
		m_pHome = nullptr;
	}
	m_pHome = home;
}


